package com.yt.server.memcached;

import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import com.danga.MemCached.MemCachedClient;
import com.yt.server.memcached.utils.MemCachedPool;
import com.yt.server.memcached.utils.MemCachedUtil;

/**
 * 集中缓存管理
 * 
 * @version 2013.10.9
 */
public class MemCachedManager {
	private static MemCachedManager manager = null;

	private MemCachedPool pool = new MemCachedPool();

	public static MemCachedManager getManager() {
		if (manager == null)
			manager = new MemCachedManager();
		return manager;
	}

	public MemCachedPool getPool() {
		return pool;
	}

	/**
	 * 加入新的集中缓存.
	 * 
	 * @param clientName
	 * @param serverlist
	 */
	public void addMemCachePool(String clientName, String... serverlist) {
		if (!pool.containsKey(clientName)) {
			pool.put(clientName,
					MemCachedUtil.getMemCachedClient(clientName, serverlist));
		}
	}

	/**
	 * 检查集中缓存的名称.
	 * 
	 * @param clientName
	 * @return
	 */
	public boolean checkCacheName(String clientName) {
		return pool.containsKey(clientName);
	}

	/**
	 * 把数据加入到指定的集中缓存.
	 * 
	 * @param clientName
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean add(String clientName, String key, Object value) {
		if (pool.containsKey(clientName)) {
			return pool.get(clientName).add(key, value);
		}
		return false;
	}

	public boolean add(String clientName, String key, Object value, Date expiry) {
		if (pool.containsKey(clientName)) {
			return pool.get(clientName).add(key, value, expiry);
		}
		return false;
	}

	/**
	 * 替换一个指定的值到缓存中.
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean replace(String clientName, String key, Object value) {
		if (pool.containsKey(clientName)) {
			return pool.get(clientName).replace(key, value);
		}
		return false;
	}

	/**
	 * update集中缓存的数据.
	 * 
	 * @param clientName
	 * @param key
	 * @param value
	 * @param expiry
	 * @return
	 */
	public boolean replace(String clientName, String key, Object value,
			Date expiry) {
		if (pool.containsKey(clientName)) {
			return pool.get(clientName).replace(key, value, expiry);
		}
		return false;
	}

	/**
	 * 删除一个指定的值到缓存中.
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean delete(String clientName, String key) {
		if (pool.containsKey(clientName)) {
			return pool.get(clientName).delete(key);
		}
		return false;
	}

	/**
	 * 根据指定的关键字删除全部缓存.
	 * 
	 * @param key
	 * @return
	 */
	public boolean deleteAll(String clientName) {
		if (pool.containsKey(clientName)) {
			for (Object object : keyset(clientName)) {
				pool.get(clientName).delete((String) object);
			}
			return true;
		}
		return false;
	}

	/**
	 * 根据指定的关键字获取对象.
	 * 
	 * @param key
	 * @return
	 */
	public Object get(String clientName, String key) {
		if (pool.containsKey(clientName)) {
			return pool.get(clientName).get(key);
		}
		return false;
	}

	/**
	 * 获取MemCachedClient.
	 * 
	 * @param clientName
	 * @return
	 */
	public MemCachedClient getMemCachedClient(String clientName) {
		if (pool.containsKey(clientName)) {
			return pool.get(clientName);
		}
		return null;
	}

	/**
	 * 根据指定的关键字遍历.
	 * 
	 * @param clientName
	 * @return
	 */
	public Set<Object> keyset(String clientName) {
		Set<Object> keys = new HashSet<Object>();
		Map<Integer, Integer> dumps = new HashMap<Integer, Integer>();
		MemCachedClient client = getMemCachedClient(clientName);
		Map<String, Map<String, String>> slabs = client.statsItems();
		if (slabs != null) {
			for (Entry<String, Map<String, String>> eSlabs : slabs.entrySet()) {
				Map<String, String> itemNames = eSlabs.getValue();
				for (Entry<String, String> eItemName : itemNames.entrySet()) {
					String itemName = eItemName.getKey();
					String[] itemAtt = itemName.split(":");
					if (itemAtt[2].startsWith("number")) {
						dumps.put(Integer.parseInt(itemAtt[1]),
								Integer.parseInt(eItemName.getValue().trim()));
					}
				}
			}
			if (!dumps.values().isEmpty()) {
				for (Entry<Integer, Integer> eDump : dumps.entrySet()) {
					int dump = eDump.getKey();
					int limit_num = eDump.getValue();
					Map cacheDump = client
							.statsCacheDump(null, dump, limit_num);
					Iterator entryIter = cacheDump.values().iterator();
					while (entryIter.hasNext()) {
						Map items = (Map) entryIter.next();
						Iterator<String> ks = items.keySet().iterator();
						while (ks.hasNext()) {
							String k = ks.next();
							try {
								k = URLDecoder.decode(k, "UTF-8");

								if (k != null && !k.trim().equals("")) {
									if (client.keyExists(k)) {
										keys.add(k);
									}
								}
							} catch (Exception ex) {
								ex.printStackTrace();
							}
						}
					}

				}
			}
		}
		return keys;
	}
}